package co.fitstart.admin.web.controller.course;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.demo2do.core.BusinessException;
import com.demo2do.core.support.Result;
import com.demo2do.core.utils.DateFormatUtils;
import com.demo2do.core.utils.DateUtils;
import com.demo2do.core.utils.JsonUtils;
import com.demo2do.core.web.utils.WebUtils;
import co.fitstart.admin.entity.content.ExpiryScheduleSearch;
import co.fitstart.admin.entity.security.Login;
import co.fitstart.admin.service.CoachService;
import co.fitstart.admin.service.CourseRoundService;
import co.fitstart.admin.service.CourseScheduleService;
import co.fitstart.admin.service.PrincipalService;
import co.fitstart.admin.service.SiteService;
import co.fitstart.admin.service.UserMonthCountService;
import co.fitstart.admin.web.interceptor.MenuSetting;
import co.fitstart.admin.web.resolver.Secure;
import co.fitstart.admin.web.view.ExcelTemplateView;
import co.fitstart.entity.course.schedule.CourseSchedule;
import co.fitstart.entity.course.schedule.ScheduleStatus;
import co.fitstart.entity.principal.Principal;
import co.fitstart.entity.site.Site;
import co.fitstart.entity.user.UserMonthCount;

/**
 * 
 * @author jiecheng
 *
 */
@Controller
@RequestMapping("/expiry-schedules")
@MenuSetting("menu-course")
public class ExpiryScheduleController {
    
    private static final Logger logger = LoggerFactory.getLogger(ExpiryScheduleController.class);
    
    @Autowired
    private CourseScheduleService courseScheduleService;
    
    @Autowired
    private UserMonthCountService userMonthCountService;
    
    @Autowired
    private CourseRoundService courseRoundService;
    
    @Autowired
    private SiteService siteService;
    
    @Autowired
    private PrincipalService principalService;
    
    @Autowired
    private CoachService coachService;
    
    /**
     * 
     * @param login
     * @param siteId
     * @param principalId
     * @param desideSiteId
     * @param request
     * @param page
     * @return
     */
    @RequestMapping(value = "", method = RequestMethod.GET)
    @MenuSetting("submenu-expiry-schedule")
    public ModelAndView list(@Secure Login login,
                             @Secure(property = "id") Long principalId,
                             @RequestParam(value = "site", required = false) Long siteId,
                             @RequestParam(value = "week", required = false, defaultValue = "1") Integer week,
                             HttpServletRequest request ) {
        
        ModelAndView modelAndView = new ModelAndView("course/expiry/expiry-schedule-list");
        modelAndView.addObject("week", week);
        
        Site site = null;
        if (!login.hasSite() && siteId != null) {
            site = siteService.load(siteId);
        }else if (login.hasSite()){
            site = login.getSite();
        }
        modelAndView.addObject("site", siteId);
        
        Date today = DateUtils.parseDate(DateFormatUtils.format(new Date(), "yyyy-MM-dd"), "yyyy-MM-dd");
        Date thisWeekBegin = DateUtils.getFirstWeekDay(today);
        Date beginDate     = DateUtils.addWeeks(thisWeekBegin, week - 1);
        Date endDate        = DateUtils.getLastWeekDay(beginDate);

        modelAndView.addObject("beginDate", beginDate);
        modelAndView.addObject("endDate", endDate);
        
        List<CourseSchedule> courseSchedules = new ArrayList<>();
        
        if(site == null && (login.isAreaManager() || login.isAreaServer())) {
            Principal principal = principalService.load(Principal.class, login.getId());
            
            List<Site> sites = siteService.listSite(principal);
            
            if(!sites.isEmpty()) {
                courseSchedules = courseScheduleService.list(sites, ScheduleStatus.EXPIRY, DateUtils.getIntervalDays(beginDate, endDate));
            }
        } else {
            courseSchedules = courseScheduleService.list(site, ScheduleStatus.EXPIRY, DateUtils.getIntervalDays(beginDate, endDate));
        }
        
        List <UserMonthCount> userMonthCounts = new ArrayList<>();
        
        for(CourseSchedule courseSchedule : courseSchedules) {
        	String thisMonth = DateFormatUtils.format(new Date(),"yyyy-MM");
        	logger.info("studentId [{}]",courseSchedule.getStudent().getId());
            UserMonthCount userMonthCount = userMonthCountService.getAllTimes(courseSchedule.getStudent().getId(), thisMonth);
            logger.info("userMonthCount [{}]",userMonthCount);
            	
            userMonthCounts.add(userMonthCount);
           
        }
        
        modelAndView.addObject("userMonthCounts",userMonthCounts);
        modelAndView.addObject("courseSchedules", courseSchedules);
        
        modelAndView.addObject("queryString", WebUtils.extractQueryString(request, "week", "site"));
        
        return modelAndView;
    }
    
    /**
     * @param scheduleId
     * @return
     */
    @RequestMapping(value = "/{scheduleId}/time", method = RequestMethod.GET)
    public ModelAndView editScheduleTime(@Secure Login login, @PathVariable("scheduleId") Long scheduleId) {
        
        ModelAndView modelAndView = new ModelAndView("course/expiry/expiry-schedule-time");
        
        CourseSchedule courseSchedule = courseScheduleService.load(CourseSchedule.class, scheduleId);
        modelAndView.addObject("schedule", courseSchedule);
        
        if(login.isAdmin() || login.isRoot()) {
            
        	List<Principal> coaches = courseScheduleService.getAllCoachs();
            
            modelAndView.addObject("coaches", coaches);
            
        } else {
        	
        	List<Principal> coaches = courseScheduleService.getSiteCoachs(siteService.load(courseSchedule.getCourseRound().getSite().getId()));
            
            modelAndView.addObject("coaches", coaches);
        	
        }
//        if(courseSchedule.getCourseType().isYear()) {
//            Map<String, Principal> coachMap = persistenceAccessor.coaches(courseSchedule.getCoach().getId(), courseSchedule.getSite().getId());
//            modelAndView.addObject("coaches", coachMap.values());
//        }
        
        return modelAndView;
    }
    
    /**
     * 
     * @param coachId
     * @return
     */
    @RequestMapping(value = "/{scheduleId}/coach-site", method = RequestMethod.POST)
    public @ResponseBody String coachSite(@RequestParam("coachId") Long coachId,
                                          @RequestParam(value = "occurDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date occurDate) {
        
        Result result = new Result();
        
        try {
            
            Principal coach = principalService.load(Principal.class, coachId);
            List<Site> sites = coachService.listCoachSite(coach, occurDate);
            
            result.success().data("sites", sites).data("siteAmount", sites.size()).message("获取教练门店成功");
            
        } catch (Exception e) {
            
            logger.error("coachSite() error:", e);
            result.fail().message("获取教练门店失败");
        }
        
        return JsonUtils.toJsonString(result);
    }
    
    
    @RequestMapping(value = "/{siteId}/site-coaches", method = RequestMethod.POST)
    public @ResponseBody String getSite(@PathVariable("siteId") Long siteId) {
        
        Result result = new Result();
        
        try {
            
                  
            if(siteId != null ) {
            	
           	    List<Principal> coaches = courseScheduleService.getSiteCoachs(siteService.load(siteId));
            	result.success().data("coaches", coaches).message("获取教练门店成功");
           }
            
            
            
        } catch (Exception e) {
            
            logger.error("getSite() error:", e);
            result.fail().message("获取教练门店失败");
        }
        
        return JsonUtils.toJsonString(result);
    }
    
    /**
     * 
     * @param scheduleId
     * @param occurDate
     * @param occurHour
     * @return
     */
    @RequestMapping(value = "/{scheduleId}/time", method = RequestMethod.PATCH)
    public @ResponseBody String onEditScheduleTime(@PathVariable("scheduleId") Long scheduleId,
                                                   @RequestParam("coachId") Long coachId,
                                                   @RequestParam(name = "siteId", required = false) Long siteId,
                                                   @RequestParam("occurDate") @DateTimeFormat(pattern = "yyyy-MM-dd") Date occurDate,
                                                   @RequestParam(value = "occurHour") String occurHour) {
        
        Result result = new Result();
        
        try {
            
            CourseSchedule courseSchedule = courseScheduleService.load(CourseSchedule.class, scheduleId);
            
            Principal coach = principalService.load(Principal.class, coachId);
            Site site = null;
            if(courseSchedule.getCourseType().isIndividual() || courseSchedule.getCourseType().isSpecial() || courseSchedule.getCourseType().isPosture()) {
                if(siteId != null) {
                    site = siteService.load(siteId);
                } else {
                    site = coachService.getCoachSite(coach);
                }
            } else {
                site = courseSchedule.getSite();
            }
            
            courseRoundService.validateEditSchedule(courseSchedule, coach, occurDate, occurHour, site);
            
            if(courseSchedule.getCourseType().isYear()) {
                courseRoundService.validateYearCourse(courseSchedule, occurDate, occurHour);
            }
            
            courseScheduleService.rearrange(courseSchedule, site, coach, occurDate, occurHour);
            
            result.success().message("修改课程时间成功");
            
        } catch(BusinessException e) {
            
            result.fail().message(e.getMessage());
            
        } catch (Exception e) {
            
            logger.error("onEditScheduleTime() error:", e);
            result.fail().message("修改课程时间失败");
        }
        
        return JsonUtils.toJsonString(result);
        
    }
    
    /**
     * @param scheduleId
     * @return
     */
    @RequestMapping(value = "/{scheduleId}/finished", method = RequestMethod.GET)
    public ModelAndView finished(@PathVariable("scheduleId") Long scheduleId) {
        
        ModelAndView modelAndView = new ModelAndView("course/expiry/expiry-schedule-finished");
        
        CourseSchedule courseSchedule = courseScheduleService.load(CourseSchedule.class, scheduleId);
        modelAndView.addObject("schedule", courseSchedule);
        
        return modelAndView;
    }
    
    /**
     * 
     * @param scheduleId 
     * @return
     */
    @RequestMapping(value = "/{scheduleId}/finished", method = RequestMethod.PATCH)
    public @ResponseBody String onFinished(@Secure Login login, @PathVariable("scheduleId") Long scheduleId) {
        
        Result result = new Result();
        
        try {
            
            CourseSchedule courseSchedule = courseScheduleService.load(CourseSchedule.class, scheduleId);
            //销课时
            courseScheduleService.finish(login, courseSchedule.getCoach(), courseSchedule);
            //减去一次逾期记录
            String thisMonth = DateFormatUtils.format(new Date(),"yyyy-MM");
            String scheduleTime = courseSchedule.occurTime();
            userMonthCountService.minusExpireTimes(thisMonth, courseSchedule.getStudent().getId(),courseSchedule.getStudent().getMobile(),scheduleTime);
            
            result.success().message("修改为已上课成功");
            
        } catch(BusinessException e){
            logger.error("#onFinished - ", e);
            result.fail().message(e.getMessage());
            
        } catch(Exception e) {
            logger.error("#onFinished - ", e);
            result.fail().message("修改为已上课失败");
            
        }
        
        return JsonUtils.toJsonString(result);
    }

    @RequestMapping(value = "/search", method = RequestMethod.GET)
    public ModelAndView search(@RequestParam(value = "site", required = false) Long siteId,
                               @RequestParam(value = "week", required = false) Integer week,
                               @RequestParam(value = "courseType", required = false) String courseType) {
        ModelAndView modelAndView = new ModelAndView("course/expiry/expiry-schedule-search");
        
        modelAndView.addObject("site", siteId);
        modelAndView.addObject("week", week);
        modelAndView.addObject("site", siteId);
        if(week != null) {
            modelAndView.addObject("targetDate", DateUtils.addWeeks(new Date(), week-1));
        }
        modelAndView.addObject("courseType", courseType);
        return modelAndView;
    }
    
    /*
     * @param week
     * @return
     */
    @RequestMapping(value = "", method = RequestMethod.GET, params = "filter")
    @MenuSetting("submenu-expiry-schedule")
    public ModelAndView onSearch(@Secure Login login,
                                 ExpiryScheduleSearch expiryScheduleSearch, 
                                 @RequestParam(value = "week", required = false) Integer week,
                                 HttpServletRequest request){
        ModelAndView modelAndView = new ModelAndView("course/expiry/expiry-schedule-list");
        modelAndView.addObject("week", week);
        
        if(login.hasSite()) {
            expiryScheduleSearch.setSite(login.getSite().getId());
            modelAndView.addObject("site", login.getSite().getId());
        } else {
            modelAndView.addObject("site", expiryScheduleSearch.getSite());
        }
        
        if(login.isAreaManager() || login.isAreaServer()) {
            Principal principal = principalService.load(Principal.class, login.getId());
            
            List<Site> sites = siteService.listSite(principal);
            
            expiryScheduleSearch.setSites(sites);
        }
        
        modelAndView.addObject("beginDate", expiryScheduleSearch.getBeginDate());
        modelAndView.addObject("endDate", expiryScheduleSearch.getEndDate());
        
        if(expiryScheduleSearch.getSites() == null || !expiryScheduleSearch.getSites().isEmpty()) {
            List<CourseSchedule> courseSchedules = courseScheduleService.expirySearch(expiryScheduleSearch);
            modelAndView.addObject("courseSchedules", courseSchedules);
        }
        
        modelAndView.addObject("refer", "search");
        modelAndView.addObject("queryString", WebUtils.extractQueryString(request, "week", "site"));

        return modelAndView;
    }
    
    /*
     * @param siteId
     * @param week
     * @return
     */
    @RequestMapping(value = "/export", method = RequestMethod.GET)
    public ModelAndView onExport(@Secure Login login,
                                 ExpiryScheduleSearch expiryScheduleSearch,
                                 @RequestParam(value = "week", required = false) Integer week,
                                 @RequestParam(value = "filter", required = false, defaultValue = "false") boolean isSearch){
        
        ModelAndView modelAndView = new ModelAndView(new ExcelTemplateView("expirySchedules.xls"));
        
        List<Site> sites = new ArrayList<>();
        List<CourseSchedule> result = new ArrayList<CourseSchedule>();
        
        if(login.isAreaManager() || login.isAreaServer()) {
            Principal areaManager = principalService.load(Principal.class, login.getId());
            
            sites = siteService.listSite(areaManager);
            
            expiryScheduleSearch.setSites(sites);
        }
        
        if(expiryScheduleSearch.getSites() == null || !expiryScheduleSearch.getSites().isEmpty()) {
            if(isSearch) {
                result = courseScheduleService.expirySearch(expiryScheduleSearch);
             } else {
                 Site site = null;
                 if (!login.hasSite() && expiryScheduleSearch.getSite() != null) {
                     site = siteService.load(expiryScheduleSearch.getSite());
                 }else if (login.hasSite()){
                     site = login.getSite();
                 }
                 
                 Date today = DateUtils.parseDate(DateFormatUtils.format(new Date(), "yyyy-MM-dd"), "yyyy-MM-dd");
                 Date thisWeekBegin = DateUtils.getFirstWeekDay(today);
                 Date beginDate     = DateUtils.addWeeks(thisWeekBegin, week - 1);
                 Date endDate        = DateUtils.getLastWeekDay(beginDate);
                 
                 if(site == null && (login.isAreaManager() || login.isAreaServer())) {
                     result = courseScheduleService.list(sites, ScheduleStatus.EXPIRY, DateUtils.getIntervalDays(beginDate, endDate));
                 }else {
                     result = courseScheduleService.list(site, ScheduleStatus.EXPIRY, DateUtils.getIntervalDays(beginDate, endDate));
                 }
             }
        }
        
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        modelAndView.addObject("courseSchedules", result);
        modelAndView.addObject("fmt", format);
        return modelAndView;
    }
}
